package com.edu.udistrital.analyzer.dao;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.type.StandardBasicTypes;

import com.edu.udistrital.analyzer.dto.SynsetDto;
import com.edu.udistrital.util.HibernateUtil;

public class AnalyzerDao {
	
	private Session sesion;
	private Transaction tx;
	
	private void iniciaOperacion() throws HibernateException {
	    sesion = HibernateUtil.getSessionFactory().openSession();
	    tx = sesion.beginTransaction();
	}
	
	private void manejaExcepcion(HibernateException he) throws HibernateException {
	    tx.rollback();
	    throw new HibernateException("Error - ", he);
	}
	
	@SuppressWarnings("unchecked")
	public List<SynsetDto> obtenerSynsets() throws HibernateException {
	    List<SynsetDto> listSynsetDto = null;
	    
	    try {
	       iniciaOperacion();
	       
	       Query query = sesion.createQuery("SELECT " +
	       		"new com.edu.udistrital.analizer.dto.SynsetDto(ev.id.pos, ev.id.offset, ev.id.word) " +
	       		"FROM EswnVariant ev");
	       
	       listSynsetDto = (List<SynsetDto>)query.list();
	       
	    } catch (HibernateException he) {
	       manejaExcepcion(he);
	    } finally {
	       sesion.close();
	    }
	    return listSynsetDto;
	}
	
	@SuppressWarnings("unchecked")
	public List<SynsetDto> obtenerRelationsSynset(SynsetDto synsetDto, Collection<String> relaciones) throws HibernateException {
		List<SynsetDto> listSinonimosSynsetDto = null;
		SynsetDto sinonimoSynsetDto = null;
		
		try {
		       iniciaOperacion();
		       
		       Query query = sesion.createSQLQuery("SELECT ev.pos AS pos, ev.offset_ AS offset, ev.word AS word " +
		       		"FROM eswn_variant ev " +
		       		"WHERE ev.offset_ IN ( " +
		       			" SELECT " +
		       			"DISTINCT(er.targetsynset) AS targetSynset " +
		       			"FROM eswn_variant ev " +
		       			"INNER JOIN eswn_relation er ON (er.sourcesynset = ev.offset_) " +
		       			"WHERE ev.offset_ = :codigoSynset AND er.relation IN (:listRelaciones) " +
		       		")").addScalar("pos", StandardBasicTypes.CHARACTER)
		       		    .addScalar("offset", StandardBasicTypes.STRING)
		       		    .addScalar("word", StandardBasicTypes.STRING);
		       
		       query.setParameter("codigoSynset", synsetDto.getCodigo());
		       query.setParameterList("listRelaciones", relaciones);
		       
		       List<Object> listObjects = query.list();
		       
		       listSinonimosSynsetDto = new ArrayList<SynsetDto>();
		       Iterator<Object> iterator = listObjects.iterator();
		       while(iterator.hasNext()) {
		    	   Object []obj = (Object[])iterator.next();
		    	   sinonimoSynsetDto = new SynsetDto();
		    	   sinonimoSynsetDto.setTipo((Character)obj[0]);
		    	   sinonimoSynsetDto.setCodigo((String)obj[1]);
		    	   sinonimoSynsetDto.setTermino((String)obj[2]);
		    	   
		    	   listSinonimosSynsetDto.add(sinonimoSynsetDto);
		       }
		       
		    } catch (HibernateException he) {
		       manejaExcepcion(he);
		    } finally {
		       sesion.close();
		    }
		    return listSinonimosSynsetDto;
	}
	
}
